Completed
Push — master ( e74965...65bae3 )
by Andres
34s
created

exotic.js ➔ ... ➔ ct.infuseBoost   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
c 1
b 0
f 0
nc 2
dl 0
loc 8
rs 9.4285
nop 1
1
/**
2
 exotic
3
 Component that handles the exotic matter and prestige logic.
4
 It includes exotic matter production, exotic upgrades, and infusion of
5
 subatomic particles to boost exotic production.
6
 A prestige erases the progress of a single element, and produces exotic
7
 matter for said element.
8
9
 @namespace Components
10
 */
11
'use strict';
12
13
angular.module('game').component('exotic', {
14
  templateUrl: 'views/exotic.html',
15
  controller:  'ct_exotic',
16
  controllerAs: 'ct'
17
});
18
19
angular.module('game').controller('ct_exotic', ['state', 'format', 'visibility', 'upgrade', 'data', 'util',
20
  function (state, format, visibility, upgrade, data, util) {
21
    let ct = this;
22
    ct.state = state;
23
    ct.data = data;
24
    ct.util = util;
25
    ct.format = format;
26
    ct.infuse = {};
27
28
    function update(player){
29
      for(let key in player.cooldowns){
30
        if(player.cooldowns[key] > 0){
31
          player.cooldowns[key]--;
32
        }
33
      }
34
    }
35
36
    /* Exotic production is a function of the different resources of each
37
    element. Additionally, multi-element molecules count double, once for
38
    each participating element. */
39
    ct.exoticProduction = function(element) {
40
      let production = {};
41
      let exoticResource = data.elements[element].exotic;
42
      production[exoticResource] = 0;
43
      for (let resource of data.elements[element].includes) {
44
        if (!state.player.resources[resource].unlocked) {
45
          continue;
46
        }
47
        for (let elem in data.resources[resource].elements) {
48
          let numberAtoms = data.resources[resource].elements[elem];
49
          let prod = prestigeFormula(state.player.resources[resource].number*numberAtoms);
50
51
          let args = {
52
            production: prod,
53
            resource: resource
54
          }
55
56
          upgrade.executeAll(data.exotic_upgrades, state.player.exotic_upgrades[elem], ['production', 'exotic'], args);
57
58
          // extract back the value from applying the upgrades
59
          let newExotic = data.elements[elem].exotic;
60
          production[newExotic] = (production[newExotic] || 0) + args.production;
61
        }
62
      }
63
      for (let key in production) {
64
        // we adjust the infusion
65
        production[key] = Math.floor(production[key]*ct.totalInfuseBoost());
66
      }
67
68
      return production;
69
    };
70
71
    function prestigeFormula(resource){
72
      let stepFactor = Math.max(Math.pow(10, Math.floor(Math.log10(resource))), 1);
73
      let step = stepFactor/data.constants.EXOTIC_STEP_QUOTIENT;
74
      let sigmoidQuotient = 1+Math.pow(Math.E, -(resource/stepFactor-data.constants.EXOTIC_SIGMOID_MAGIC));
75
      let sigmoid = 1/sigmoidQuotient+0.1;
76
      return Math.floor(step * sigmoid);
77
    }
78
79
    ct.exoticPrestige = function(index) {
80
      let slot = state.player.element_slots[index];
81
      let resources = state.player.resources;
82
      let cooldown = state.player.cooldowns[index];
83
      let production = 0;
84
      if(cooldown === 0){
85
        production = ct.exoticProduction(slot.element);
86
      }
87
88
      for (let key in production) {
89
        resources[key].number += production[key];
90
        resources[key].unlocked = true;
91
      }
92
93
      for(let resource in ct.infuse){
94
        state.player.resources[resource].number -= ct.infuse[resource];
95
      }
96
97
      upgrade.resetElement(state.player, slot.element);
98
99
      // we deactivate reactions and redoxes
100
      for (let reaction of slot.reactions) {
101
        reaction.active = false;
102
      }
103
104
      for (let redox of slot.redoxes) {
105
        redox.active = false;
106
      }
107
108
      // we cache them in case players want to pick up the same element
109
      // the cache only lasts the current session
110
      state.reactionsCache[slot.element] = slot.reactions;
111
      state.redoxesCache[slot.element] = slot.redoxes;
112
113
      state.player.element_slots[index] = null;
114
115
      if(cooldown === 0){
116
        state.player.cooldowns[index] = 60*60;
117
      }
118
    };
119
120
    ct.buyExoticUpgrade = function(name, slot) {
121
      let price = data.exotic_upgrades[name].price;
122
      let currency = data.elements[slot.element].exotic;
123
      upgrade.buyUpgrade(state.player,
124
        state.player.exotic_upgrades[slot.element],
125
        data.exotic_upgrades[name],
126
        name,
127
        price,
128
        currency);
129
    };
130
131
    ct.setPercentage = function(resource, percentage) {
132
      ct.infuse[resource] = Math.floor(state.player.resources[resource].number*(percentage/100));
133
    };
134
135
    ct.fixNumber = function(resource) {
136
      ct.infuse[resource] = Math.max(0, Math.min(state.player.resources[resource].number, ct.infuse[resource]));
137
    };
138
139
    /* This function checks that values inserted in the text boxes are
140
    valid numbers */
141
    ct.isValidInfusion = function() {
142
      let valid = true;
143
      for(let resource in ct.infuse){
144
        valid = valid && Number.isFinite(ct.infuse[resource]);
145
      }
146
      return valid;
147
    };
148
149
    ct.infuseBoost = function(resource) {
150
        let number = Math.min(ct.infuse[resource], state.player.resources[resource].number);
151
        if(number === 0){
152
          return 1;
153
        }
154
        // log adds diminishing returns to the infusion
155
        return 1 + Math.log(number)/Math.log(1.25)*ct.data.constants.INFUSE_POWER;
156
    };
157
158
    /* The infusion boosts are multiplicative with respect to each other */
159
    ct.totalInfuseBoost = function() {
160
      let total = 1;
161
      for(let resource in ct.infuse){
162
        total *= ct.infuseBoost(resource);
163
      }
164
      return total;
165
    };
166
167
    ct.visibleExoticUpgrades = function(slot) {
168
      return visibility.visible(data.exotic_upgrades, isExoticUpgradeVisible, slot);
169
    };
170
171
    function isExoticUpgradeVisible(name, slot) {
172
      return visibility.isUpgradeVisible(name, slot, data.exotic_upgrades[name]);
173
    }
174
175
    ct.visibleSubatomic = function() {
176
      return visibility.visible(data.resources, isSubatomicVisible, '');
177
    };
178
179
    function isSubatomicVisible(name) {
180
      if (!state.player.resources[name].unlocked) {
181
        return false;
182
      }
183
184
      if(data.resources[name].type &&
185
         data.resources[name].type.indexOf('subatomic') !== -1){
186
          return true;
187
      }
188
189
      return false;
190
    }
191
192
    state.registerUpdate('exotic', update);
193
  }
194
]);
195